home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / asm-m68k / floppy.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  5.1 KB  |  255 lines

  1. /*
  2.  * Implementation independent bits of the Floppy driver.
  3.  *
  4.  * much of this file is derived from what was originally the Q40 floppy driver.
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License.  See the file "COPYING" in the main directory of this archive
  8.  * for more details.
  9.  *
  10.  * Copyright (C) 1999, 2000, 2001
  11.  *
  12.  * Sun3x support added 2/4/2000 Sam Creasey (sammy@sammy.net)
  13.  *
  14.  */
  15.  
  16. #include <asm/io.h>
  17.  
  18. #include <linux/vmalloc.h>
  19.  
  20. asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id);
  21.  
  22. /* constants... */
  23.  
  24. #undef MAX_DMA_ADDRESS
  25. #define MAX_DMA_ADDRESS   0x00  /* nothing like that */
  26.  
  27.  
  28. /*
  29.  * Again, the CMOS information doesn't work on m68k..
  30.  */
  31. #define FLOPPY0_TYPE (MACH_IS_Q40 ? 6 : 4)
  32. #define FLOPPY1_TYPE 0
  33.  
  34. /* basically PC init + set use_virtual_dma */
  35. #define  FDC1 m68k_floppy_init()
  36.  
  37. #define N_FDC 1
  38. #define N_DRIVE 8
  39.  
  40.  
  41. /* vdma globals adapted from asm-i386/floppy.h */
  42.  
  43. static int virtual_dma_count=0;
  44. static int virtual_dma_residue=0;
  45. static char *virtual_dma_addr=NULL;
  46. static int virtual_dma_mode=0;
  47. static int doing_pdma=0;
  48.  
  49. #include <asm/sun3xflop.h>
  50.  
  51. extern spinlock_t  dma_spin_lock;
  52.  
  53. static __inline__ unsigned long claim_dma_lock(void)
  54. {
  55.     unsigned long flags;
  56.     spin_lock_irqsave(&dma_spin_lock, flags);
  57.     return flags;
  58. }
  59.  
  60. static __inline__ void release_dma_lock(unsigned long flags)
  61. {
  62.     spin_unlock_irqrestore(&dma_spin_lock, flags);
  63. }
  64.  
  65.  
  66. static __inline__ unsigned char fd_inb(int port)
  67. {
  68.     if(MACH_IS_Q40)
  69.         return inb_p(port);
  70.     else if(MACH_IS_SUN3X)
  71.         return sun3x_82072_fd_inb(port);
  72.     return 0;
  73. }
  74.  
  75. static __inline__ void fd_outb(unsigned char value, int port)
  76. {
  77.     if(MACH_IS_Q40)
  78.         outb_p(value, port);
  79.     else if(MACH_IS_SUN3X)
  80.         sun3x_82072_fd_outb(value, port);
  81. }
  82.  
  83.  
  84. static int fd_request_irq(void)
  85. {
  86.     if(MACH_IS_Q40)
  87.         return request_irq(FLOPPY_IRQ, floppy_hardint,
  88.                    IRQF_DISABLED, "floppy", floppy_hardint);
  89.     else if(MACH_IS_SUN3X)
  90.         return sun3xflop_request_irq();
  91.     return -ENXIO;
  92. }
  93.  
  94. static void fd_free_irq(void)
  95. {
  96.     if(MACH_IS_Q40)
  97.         free_irq(FLOPPY_IRQ, floppy_hardint);
  98. }
  99.  
  100. #define fd_request_dma()        vdma_request_dma(FLOPPY_DMA,"floppy")
  101. #define fd_get_dma_residue()    vdma_get_dma_residue(FLOPPY_DMA)
  102. #define fd_dma_mem_alloc(size)    vdma_mem_alloc(size)
  103. #define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io)
  104.  
  105. #define fd_enable_irq()           /* nothing... */
  106. #define fd_disable_irq()          /* nothing... */
  107.  
  108. #define fd_free_dma()             /* nothing */
  109.  
  110. /* No 64k boundary crossing problems on Q40 - no DMA at all */
  111. #define CROSS_64KB(a,s) (0)
  112.  
  113. #define DMA_MODE_READ  0x44    /* i386 look-alike */
  114. #define DMA_MODE_WRITE 0x48
  115.  
  116.  
  117. static int m68k_floppy_init(void)
  118. {
  119.   use_virtual_dma =1;
  120.   can_use_virtual_dma = 1;
  121.  
  122.  
  123.   if (MACH_IS_Q40)
  124.       return 0x3f0;
  125.   else if(MACH_IS_SUN3X)
  126.       return sun3xflop_init();
  127.   else
  128.     return -1;
  129. }
  130.  
  131.  
  132. static int vdma_request_dma(unsigned int dmanr, const char * device_id)
  133. {
  134.     return 0;
  135. }
  136.  
  137.  
  138. static int vdma_get_dma_residue(unsigned int dummy)
  139. {
  140.     return virtual_dma_count + virtual_dma_residue;
  141. }
  142.  
  143.  
  144. static unsigned long vdma_mem_alloc(unsigned long size)
  145. {
  146.     return (unsigned long) vmalloc(size);
  147.  
  148. }
  149.  
  150. static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
  151. {
  152.         vfree((void *)addr);
  153. }
  154. #define fd_dma_mem_free(addr,size) _fd_dma_mem_free(addr, size)
  155.  
  156.  
  157. /* choose_dma_mode ???*/
  158.  
  159. static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
  160. {
  161.     doing_pdma = 1;
  162.     virtual_dma_port = (MACH_IS_Q40 ? io : 0);
  163.     virtual_dma_mode = (mode  == DMA_MODE_WRITE);
  164.     virtual_dma_addr = addr;
  165.     virtual_dma_count = size;
  166.     virtual_dma_residue = 0;
  167.     return 0;
  168. }
  169.  
  170.  
  171.  
  172. static void fd_disable_dma(void)
  173. {
  174.     doing_pdma = 0;
  175.     virtual_dma_residue += virtual_dma_count;
  176.     virtual_dma_count=0;
  177. }
  178.  
  179.  
  180.  
  181. /* this is the only truly Q40 specific function */
  182.  
  183. asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id)
  184. {
  185.     register unsigned char st;
  186.  
  187. #undef TRACE_FLPY_INT
  188. #define NO_FLOPPY_ASSEMBLER
  189.  
  190. #ifdef TRACE_FLPY_INT
  191.     static int calls=0;
  192.     static int bytes=0;
  193.     static int dma_wait=0;
  194. #endif
  195.     if(!doing_pdma) {
  196.         floppy_interrupt(irq, dev_id);
  197.         return IRQ_HANDLED;
  198.     }
  199.  
  200. #ifdef TRACE_FLPY_INT
  201.     if(!calls)
  202.         bytes = virtual_dma_count;
  203. #endif
  204.  
  205.     {
  206.         register int lcount;
  207.         register char *lptr;
  208.  
  209.         /* serve 1st byte fast: */
  210.  
  211.         st=1;
  212.         for(lcount=virtual_dma_count, lptr=virtual_dma_addr;
  213.             lcount; lcount--, lptr++) {
  214.             st=inb(virtual_dma_port+4) & 0xa0 ;
  215.             if(st != 0xa0)
  216.                 break;
  217.             if(virtual_dma_mode)
  218.                 outb_p(*lptr, virtual_dma_port+5);
  219.             else
  220.                 *lptr = inb_p(virtual_dma_port+5);
  221.         }
  222.  
  223.         virtual_dma_count = lcount;
  224.         virtual_dma_addr = lptr;
  225.         st = inb(virtual_dma_port+4);
  226.     }
  227.  
  228. #ifdef TRACE_FLPY_INT
  229.     calls++;
  230. #endif
  231.     if(st == 0x20)
  232.         return IRQ_HANDLED;
  233.     if(!(st & 0x20)) {
  234.         virtual_dma_residue += virtual_dma_count;
  235.         virtual_dma_count=0;
  236. #ifdef TRACE_FLPY_INT
  237.         printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n",
  238.                virtual_dma_count, virtual_dma_residue, calls, bytes,
  239.                dma_wait);
  240.         calls = 0;
  241.         dma_wait=0;
  242. #endif
  243.         doing_pdma = 0;
  244.         floppy_interrupt(irq, dev_id);
  245.         return IRQ_HANDLED;
  246.     }
  247. #ifdef TRACE_FLPY_INT
  248.     if(!virtual_dma_count)
  249.         dma_wait++;
  250. #endif
  251.     return IRQ_HANDLED;
  252. }
  253.  
  254. #define EXTRA_FLOPPY_PARAMS
  255.